﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ApprovalFlow.Interface;

namespace ApprovalFlow.Primitives
{
    /// <summary>
    /// 审批节点
    /// </summary>
    public class Approval : StepBody, ITaskStep
    {
        readonly IUserProvider _userProvider;

        public Approval(IUserProvider userProvider)
        {
            _userProvider = userProvider;
        }

        public override ExecutionResult Run(IStepExecutionContext context)
        {
            if (context.ExecutionPointer.EventData is null)
            {
                return ExecutionResult.WaitForEvent();
            }
            else if (context.ExecutionPointer.EventData is Models.ApprovalActionOptions options)
            {
                string user_id = _userProvider.UserID;
                var action_type = context.ExecutionPointer.ExtensionAttributes["action_type"] as string;  //多人审批时采用的审批方式
                var user_list = context.ExecutionPointer.ExtensionAttributes["action_user_list"] as string[]; //多人审批的审批用户列表

                Models.Approval.ExecutionPointerExtension extension = default;
                if (context.ExecutionPointer.PersistenceData is null)
                {
                    extension = new Models.Approval.ExecutionPointerExtension();
                    user_list.ToList().ForEach(user_id => extension.Status[user_id] = "pending");
                    context.ExecutionPointer.PersistenceData = extension;
                }
                else
                {
                    extension = (Models.Approval.ExecutionPointerExtension)context.ExecutionPointer.PersistenceData;
                }

                switch (options.Result)
                {
                    case "agree":  //通过

                        // 处理审批动作
                        extension.Status[user_id] = "agree";

                        //处理完成后根据审批方式决定要不要跳出该节点
                        switch (action_type)
                        {
                            case "AND": //指同一个审批节点设置多个人，如ABC三人，三人会同时收到审批，需全部同意之后，审批才可到下一审批节点；
                                if (extension.Status.ToList().TrueForAll(x => x.Value == "agree"))
                                    return ExecutionResult.Next();
                                else
                                    return ExecutionResult.Unfinished();
                            case "OR": //指同一个审批节点设置多个人，如ABC三人，三人会同时收到审批，只要其中任意一人审批即可到下一审批节点；          
                                return ExecutionResult.Next();
                            case "NONE": //当多个审批人都在同一个节点时，审批顺序有先后，先后规则为管理员先选择的人就先进行审批；
                                if (extension.Status.ToList().TrueForAll(x => x.Value == "agree"))
                                    return ExecutionResult.Next();
                                else
                                    return ExecutionResult.Unfinished();
                        }
                        break;
                    case "refuse": //拒绝
                        extension.Status[user_id] = "refuse";
                        return ExecutionResult.EndWorkFlow();
                    //case "redirect": //转交
                    //    // 原则：如果多人的情况下，则禁止转交。
                    //    ExecutionPointer pointer = new()
                    //    {
                    //        Id = Guid.NewGuid().ToString(),
                    //        InstanceId = context.ExecutionPointer.InstanceId,
                    //        PredecessorId = context.ExecutionPointer.Id,
                    //        StepID = context.ExecutionPointer.StepID,
                    //        StepName = context.ExecutionPointer.StepName,
                    //        ExtensionAttributes = new()
                    //        {
                    //            ["action_type"] = "AND",
                    //            ["action_user_list"] = new string[] { options .},
                    //        }
                    //    };                        
                    //    var pointers = context.Workflow.ExecutionPointers.Where(x => x.PredecessorId == context.ExecutionPointer.Id).ToList();
                    //    pointers.ForEach(x => x.PredecessorId = pointer.Id);
                    //    context.Workflow.ExecutionPointers.Add(pointer);

                    //    return ExecutionResult.Next();
                    default:
                        throw new NotImplementedException();
                }
                Console.WriteLine($"[{context.ExecutionPointer.StepName}]- {options.Result}了审批,描述:{options.Remark}");
            }
            return ExecutionResult.Next();

        }
    }
}
